﻿using System;
using System.Windows.Forms;
using System.ComponentModel.Design;
using System.Collections.Generic;
using System.ComponentModel;
using UtfprLibrary.Windows.Forms.Exceptions;

namespace UtfprLibrary.Windows.Forms.Helpers {
    /// <summary>
    /// TODO
    /// </summary>
    public static class UtfprControlHelper {
        /// <summary>
        /// TODO
        /// </summary>
        /// <param name="control"></param>
        /// <returns></returns>
        public static Form FindForm(Control control) {
            try {
                if (control == null) {
                    throw new ArgumentNullException("control cannot be null.");
                }

                var form = control.FindForm();
                if (form != null) {
                    return form;
                } else {
                    if (control.Container == null) {
                        throw new ArgumentException("Could not find Container.");
                    }

                    var root = (control.Container as IDesignerHost).RootComponent;
                    if (root.GetType() == typeof(Form) || root.GetType().IsSubclassOf(typeof(Form))) {
                        return root as Form;
                    } else {
                        throw new ArgumentException("Could not find Form.");
                    }
                }
            } catch (Exception ex) {
                throw new UtfprWFCoreHelpersException("", ex);
            }
        }
        
        /// <summary>
        /// TODO
        /// </summary>
        /// <param name="controls"></param>
        /// <returns></returns>
        public static List<Control> FindControls(Control.ControlCollection controls) {
            try {
                var allControls = new List<Control>();

                foreach (Control c in controls) {
                    allControls.Add(c);

                    var innerControls = FindControls(c.Controls);

                    for (int i = 0; i < innerControls.Count; i++) {
                        allControls.Add(innerControls[i]);
                    }

                }

                return allControls;
            } catch (Exception ex) {
                throw new UtfprWFCoreHelpersException("", ex);
            }
        }

        /// <summary>
        /// TODO
        /// </summary>
        internal static List<DataGridView> findDataGridViews(Control.ControlCollection controls) {
            try {
                var grids = new List<DataGridView>();

                foreach (Control control in controls) {
                    if (control.GetType() == typeof(DataGridView)) {
                        grids.Add(control as DataGridView);
                    } else {
                        var innerGrids = findDataGridViews(control.Controls);

                        for (int i = 0; i < innerGrids.Count; i++) {
                            grids.Add(innerGrids[i]);
                        }
                    }
                }

                return grids;
            } catch (Exception ex) {
                throw new UtfprWFCoreHelpersException("", ex);
            }
        }

        /// <summary>
        /// TODO
        /// </summary>
        /// <param name="bindingSource"></param>
        /// <returns></returns>
        public static Type GetDataSourceType(BindingSource bindingSource) {
            try {
                if (bindingSource == null) {
                    return null;
                }

                var propertyCollection = (bindingSource as ITypedList).GetItemProperties(null);

                if (propertyCollection == null || propertyCollection.Count == 0) {
                    return null;
                }

                return propertyCollection[0].ComponentType;
            } catch (Exception ex) {
                throw new UtfprWFCoreHelpersException("", ex);
            }
        }
        
        /// <summary>
        /// TODO
        /// </summary>
        /// <param name="bindingSource"></param>
        /// <returns></returns>
        internal static List<string> getDataMembers(BindingSource bindingSource) {
            try {
                List<string> dataMembers = new List<string>();

                if (bindingSource.DataMember != string.Empty) {
                    dataMembers.Add(bindingSource.DataMember);

                    var innerDataMembers = getDataMembers(bindingSource.DataSource as BindingSource);

                    foreach (var dataMember in innerDataMembers) {
                        dataMembers.Add(dataMember);
                    }
                }

                return dataMembers;
            } catch (Exception ex) {
                throw new UtfprWFCoreHelpersException("", ex);
            }
        }
    }
}
